/**
 * 
 */
package org.mspring.crm.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;

import org.apache.log4j.Logger;
import org.mspring.crm.client.common.ItemType;
import org.mspring.crm.dao.permission.ItemDao;
import org.mspring.crm.entity.permission.Item;
import org.mspring.crm.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Gao Youbo
 * @since Feb 20, 2012
 */
@Service
@Transactional
public class ItemServiceImpl implements ItemService {

    private static final Logger log = Logger.getLogger(ItemServiceImpl.class);

    private ItemDao itemDao;

    @Autowired
    public void setItemDao(ItemDao itemDao) {
        this.itemDao = itemDao;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.mspring.crm.service.ItemService#generateTreeItem(java.lang.Integer)
     */
    public List<Item> generateTreeItem(Integer userId, Integer parentId) {
        // TODO Auto-generated method stub
        List<Item> treeItemsByUser = generateTreeItemByUser(userId, parentId);
        List<Item> treeItemsByRole = generateTreeItemByRole(userId, parentId);
        List<Item> treeItemsByUserGroup = generateTreeItemByUserGroup(userId, parentId);
        List<Item> treeItemsByRoleGroup = generateTreeItemByRoleGroup(userId, parentId);
        return sortAndRemoveRepeatedItem(treeItemsByUser, treeItemsByRole, treeItemsByUserGroup, treeItemsByRoleGroup);
    }

    private List<Item> generateTreeItemByUser(Integer userId, Integer parentId) {
        StringBuffer queryString = new StringBuffer();
        queryString.append("select item from Item item , UserItem userItem ");
        queryString.append("where item.id = userItem.userItemPK.itemId and userItem.userItemPK.userId = ? ");
        queryString.append("and item.parent = ? and item.type = ? ");
        return itemDao.find(queryString.toString(), new Integer[]{userId, parentId, ItemType.treeitem});
    }

    private List<Item> generateTreeItemByRole(Integer userId, Integer parentId) {
        StringBuffer queryString = new StringBuffer();
        queryString.append("select item from Item item , UserRole userRole, RoleItem roleItem ");
        queryString.append("where roleItem.roleItemPK.itemId = item.id ");
        queryString.append("and userRole.userRolePK.roleId = roleItem.roleItemPK.roleId ");
        queryString.append("and userRole.userRolePK.userId = ? ");
        queryString.append("and item.parent = ? and item.type = ? ");
        return itemDao.find(queryString.toString(), new Integer[]{userId, parentId, ItemType.treeitem});
    }

    private List<Item> generateTreeItemByUserGroup(Integer userId, Integer parentId) {
        StringBuffer queryString = new StringBuffer();
        queryString.append("select item from Item item, UserGroup userGroup, GroupItem groupItem ");
        queryString.append("where item.id = groupItem.groupItemPK.itemId ");
        queryString.append("and userGroup.userGroupPK.groupId = groupItem.groupItemPK.groupId ");
        queryString.append("and userGroup.userGroupPK.userId = ? ");
        queryString.append("and item.parent = ? and item.type = ? ");
        return itemDao.find(queryString.toString(), new Integer[]{userId, parentId, ItemType.treeitem});
    }

    private List<Item> generateTreeItemByRoleGroup(Integer userId, Integer parentId) {
        StringBuffer queryString = new StringBuffer();
        queryString.append("select item from Item item, GroupItem groupItem, UserRole userRole, RoleGroup roleGroup ");
        queryString.append("where item.id = groupItem.groupItemPK.itemId ");
        queryString.append("and groupItem.groupItemPK.groupId = roleGroup.roleGroupPK.groupId ");
        queryString.append("and userRole.userRolePK.roleId = roleGroup.roleGroupPK.roleId ");
        queryString.append("and userRole.userRolePK.userId = ? ");
        queryString.append("and item.parent = ? and item.type = ? ");
        return itemDao.find(queryString.toString(), new Integer[]{userId, parentId, ItemType.treeitem});
    }

    private List<Item> sortAndRemoveRepeatedItem(List<Item>... items) {
        List<Item> list = new ArrayList<Item>();
        if (items != null && items.length > 0) {
            for (int i = 0; i < items.length; i++)
                if (null != items[i] && items[i].size() > 0)
                    list.addAll(items[i]);
        }

        // 排序
        Collections.sort(list, new Comparator<Item>() {
            public int compare(Item o1, Item o2) {
                // TODO Auto-generated method stub
                return o1.getId().compareTo(o1.getId());
            }
        });

        // 剔重
        Integer tempItemId = new Integer("-1");
        if (list != null && !list.isEmpty()) {
            for (ListIterator<Item> lit = list.listIterator(); lit.hasNext();) {
                Item item = lit.next();
                if (tempItemId.compareTo(item.getId()) == 0) {
                    lit.remove();
                } else {
                    tempItemId = item.getId();
                }
            }
        }
        return list;
    }

    /* (non-Javadoc)
     * @see org.mspring.crm.service.ItemService#findItemByTypeAndParent(java.lang.Integer, java.lang.Integer)
     */
    @Override
    public List<Item> findItemByTypeAndParent(Integer parent, Integer type) {
        // TODO Auto-generated method stub
        String queryString = " from Item item where item.parent = ? and item.type = ?";
        return itemDao.find(queryString, new Integer[]{parent, type});
    }
}
